package cn.admin.configcenter.registry.common.event;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

public class EventDispatcher {

    private static final Logger LOG = LoggerFactory.getLogger(EventDispatcher.class);
    private static final Map<Class<? extends Event>, CopyOnWriteArrayList<EventListener>>
            listenerMap = new HashMap<>();

    public static void addEventListener(EventListener listener) {

        for (Class<? extends Event> type : listener.interest()) {
            getListenerList(type).addIfAbsent(listener);
        }

    }

    public static void fireEvent(Event event) {
        if (event != null) {
            for (Event implyEvent : event.implyEvents()) {
                try {
                    if (event != implyEvent) {
                        fireEvent(implyEvent);
                    }
                } catch (Exception e) {
                    LOG.error(e.toString(), e);
                }
            }

            for (EventListener listener : getListenerList(event.getClass())) {
                try {
                    listener.onEvent(event);
                } catch (Exception e) {
                    LOG.error(e.toString(), e);
                }
            }
        }
    }

    private static CopyOnWriteArrayList<EventListener> getListenerList(Class<? extends Event> eventType) {
        CopyOnWriteArrayList<EventListener> listeners = listenerMap.get(eventType);

        if (listeners == null) {
            listeners = new CopyOnWriteArrayList<>();
            listenerMap.put(eventType,listeners);
        }

        return listeners;
    }

}
